const express = require('express')
const router = express.Router()
const $sql = require('../sqlMap')
var sqlite3 = require('sqlite3').verbose()
const csv = require('csvtojson')
const iconv = require('iconv-lite');
const csvHepler = require('../utils/csvHepler')
const transfer = require('../utils/transfer')

var nodes7 = require('nodes7');
const e = require('express');
var conn = new nodes7;
var doneReading = false;
var doneWriting = false;
var PLCresult;

var initConfig;



/**
 * @function: sql
 * @description: 数据库连接
 * @author: allen
 * @version: 1.0.0
 * @param {*}
 * @return {*}
 */
var db = new sqlite3.Database('DB.db', (err)=>{
  if (err) throw err;
  console.log('数据库连接')
})

// 每隔一段时间执行一次任务
setInterval(function timer() {
  // 从数据库中获取节点数据
  const sql = $sql.Map.getTrendList
  db.all(sql,function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      // 记录数据到csv文件
      csvHepler.recordData(result,conn)
      // console.log(result)
    }
  })

  // 打印任务执行时间
  console.warn(`[${transfer.formatDate(new Date())}] trend event running.`)

}, 1 * 1000)




conn.initiateConnection({ port: 102, host: '172.168.0.5', rack: 0, slot: 1, debug: false }, connected);
function connected(err) {
  if (typeof(err) !== "undefined") {
    console.log(err);
    console.error(`PLC error connect`)
    // process.exit();
    // conn.initiateConnection({ port: 102, host: '192.168.0.1', rack: 0, slot: 1, debug: false }, connected);
  }
}

function valuesReady(anythingBad, values) {
  // if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
  console.log(values)
  PLCresult = values
  console.log("----",PLCresult)
  doneReading = true;
  if (doneWriting) { process.exit(); }
}

function valuesWritten(anythingBad) {
  if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
  console.log("Done writing.");
  doneWriting = true;
  if (doneReading) { process.exit(); }
}





router.post('/user/login', (req, res) => {
  const sql = $sql.Map.getUser
  const params = req.body
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/user/login")
  console.log("params: ", req.body)
  console.log("sql: " , sql)
  db.all(sql,[params.username,params.password],function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result, 100)
    }
  })
})

/**
 * CODE == 200
 * get user info by token : token
 */
router.get('/user/info', (req, res) => {
  const sql = $sql.Map.getUserByToken
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/user/info")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  db.all(sql,[params.token],function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result , 200)
    }
  })
})

/**
 * CODE == 300
 * get plc address table : table
 * get plc data use S7
 * exp : conn.addItems(['TEST13','TEST11'])
 * exp : conn.addItems('DB100,Real0')
 */
router.get('/table/getList', (req, res) => {
  const sql = $sql.Map.getTableList
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/table/list")
  console.log("sql: " , sql)
  db.all(sql,function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {

      //1.add item to plc
      result.forEach(e => {
        // console.log(e.address)
        conn.addItems(e.address)
      });

      //2.call function
      conn.readAllItems((anythingBad, values) => {
        if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }

        //1.replace data : value
        for (var i=0;i<result.length;i++){

          //update value
          result[i].value = values[result[i].address].toFixed(2)

          //update date
          result[i].date = transfer.formatDate(new Date())

        }

        //feedback url
        transfer.jsonWrite(res, result , 300)

        // console.log(result)
        console.log("--values-->>",values)
        doneReading = true;
        if (doneWriting) { process.exit(); }
      });

    }
  })
})


/**
 * CODE == 500  [write no feedback]
 * set plc data value = update
 */
router.get('/table/setWrite', (req, res) => {
  const sql = $sql.Map.setWriteData
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/table/write")
  console.log("params: ", req.query)
  console.log("sql: " , sql)


  //1.write PLC
  conn.writeItems(params.address, params.value, valuesWritten)

  //2.write db
  db.all(sql,[params.value,transfer.formatDate(new Date()), params.id],function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result , 500)
    }
  })
})

/**
 * CODE == 600
 * set plc data value = update
 */
router.get('/table/getWriteList', (req, res) => {
  const sql = $sql.Map.getWriteData
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/table/writelist")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  db.all(sql,function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result , 600)
    }
  })
})

/**
 * CODE == 500
 * set plc data value = update
 */
router.get('/table/delTableList', (req, res) => {
  const sql = $sql.Map.delTableList
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/table/delTableList")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  db.all(sql,[params.id],function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result , 500)
    }
  })
})

/**
 * CODE == 200
 * download all parameter to plc
 */
router.get('/table/downloadTableList', (req, res) => {
  const sql = $sql.Map.getWriteData
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/table/downloadTableList")
  // console.log("params: ", req.query)


  //download par to plc batch
  // conn.writeItems(params.address, params.value, valuesWritten)
  // conn.writeItems(['DB100,Real12','DB100,Real16'], [1000,2000], valuesWritten)

  db.all(sql,function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {

      //write to plc

      console.log(result[0].address)

      var adrItem = []
      var valueItem = []

      result.forEach(e => {
        adrItem.push(e.address)
        valueItem.push(e.value)
      });

      if (adrItem != null ){
        conn.writeItems(adrItem,valueItem,valuesWritten)
      }

      transfer.jsonWrite(res, '' , 600)
    }
  })


})

/**
 * CODE == 500  [ no feedback]
 * add node
 */
router.get('/table/addNode', (req, res) => {
  const sql = $sql.Map.addNode
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/table/addNode")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  if(params != null){
    db.all(sql,[params.plc,params.address,params.type,params.status,params.rw,params.property,params.desc,params.date],function(err,result){
      if (err) {
        console.log(err)
      }
      if (result) {
        transfer.jsonWrite(res, result , 500)
      }
    })
  }

})

//----------------TREND-----------------------------

/**
 * CODE == 500  [ no feedback]
 * add node
 */
router.post('/trend/addTrendList', (req, res) => {
  const sql = $sql.Map.addTrendList
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/trend/addTrendList")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  if(params != null ){
    db.all(sql,[params.plc,params.address,params.type,params.status,params.rw,params.factory,params.property,params.desc,params.date],function(err,result){
      if (err) {
        console.log(err)
      }
      if (result) {
        transfer.jsonWrite(res, result , 500)
      }
    })
  }

})

/**
 * CODE == 600
 * set plc data value = update
 */
router.get('/trend/getTrendList', (req, res) => {
  const sql = $sql.Map.getTrendList
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/trend/getTrendList")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  db.all(sql,function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result , 600)
    }
  })
})

/**
 * CODE == 600
 * set plc data value = update
 */
router.get('/trend/getTendItem', (req, res) => {
  const sql = $sql.Map.getTendItem
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/trend/getTendItem")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  db.all(sql,function(err,result){
    if (err) {
      console.log(err)
    }
    if (result) {
      transfer.jsonWrite(res, result , 600)
    }
  })
})

/**
 * CODE == 500  [ no feedback]
 * add node
 */
router.post('/trend/updateTrendList', (req, res) => {
  const sql = $sql.Map.updateTrendList
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/trend/updateTrendList")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  if(params != null ){
    db.all(sql,[params.factory,params.id],function(err,result){
      if (err) {
        console.log(err)
      }
      if (result) {
        transfer.jsonWrite(res, result , 500)
      }
    })
  }

})


/**
 * CODE == 500  [ no feedback]
 * add node
 */
router.post('/trend/delTrendList', (req, res) => {
  const sql = $sql.Map.delTrendList
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/trend/delTrendList")
  console.log("params: ", req.query)
  console.log("sql: " , sql)
  if(params != null ){
    db.all(sql,[params.id],function(err,result){
      if (err) {
        console.log(err)
      }
      if (result) {
        transfer.jsonWrite(res, result , 500)
      }
    })
  }

})


/**
 * CODE == 700  [ JSON feedback  ]
 * add node
 */

var dataCSV = [];
var dataSearchData = [];
var startTime = ''
var endTime = ''

router.post('/trend/searchTrend', (req, res) => {
  const params = req.query
  console.log("------------------------------------------")
  console.log("http://localhost:3000/api/trend/searchTrend")

  if(params != null ){

    dataCSV = []
    dataSearchData = []

    var tag = params.currentSelectTag
    var start = params.currentSelectDate[0]
    var end = params.currentSelectDate[1]

    var tempStart = start.slice(0,10)
    var tempEnd = end.slice(0,10)
    var prefix = "./trend/"
    var suffix = "/" + tag + ".csv"
    var filePath = transfer.getAllDate(tempStart,tempEnd,prefix,suffix)

    startTime = start
    endTime = end

    console.log(startTime)
    console.log(endTime)

    console.log(filePath)
    f(filePath,res)
  }
})

/**
 * 异步函数：从CSV文件中读取数据并转换为指定编码格式
 * @param {string} filePath - 文件路径
 */
async function getFileData(filePath){
  // 使用csv()函数从文件路径中读取CSV文件，并指定编码为binary
  const converter = await csv()
  .fromFile(filePath,{encoding:'binary'})
  .then((json) => {
    // 将JSON对象转换为GBK编码的字符串
    var buf =  Buffer(JSON.stringify(json), 'binary');
    var str = iconv.decode(buf, 'GBK');
    // 由于上一步得到的结果是字符串，此处将其转换为JSON格式
    str=JSON.parse(JSON.stringify(str))
    // 使用eval将字符串转换为JavaScript对象
    var result =eval(str)
    console.log(result)
    // 将数据添加到dataCSV数组中
    dataCSV.push(str)
  })
}

/**
 * 异步函数f，用于处理文件路径数组，返回处理结果
 * @param {Array} filePath - 文件路径数组
 * @param {Object} res - 响应对象，用于最终结果的返回
 * @param {Object} params - 其他参数对象，本例中未使用
 */
async function f(filePath,res,params) {
  // 遍历文件路径数组，异步获取每个文件的数据
  for (const e of filePath) {
    const res = await getFileData(e)
  }

  // 遍历数据数组，筛选符合条件的数据
  for  (var e of dataCSV) {
    // 将字符串数据转换为对象
    var  data = eval(e)
    // 遍历转换后的数据对象
    for  (const e of data) {
      // 创建当前时间对象
      let currentTime = new Date(e.time )
      // 创建开始时间对象
      let start = new Date(startTime)
      // 创建结束时间对象
      let end = new Date(endTime)

      // 检查当前时间是否在开始和结束时间之间
      if (currentTime >=  start && currentTime <= end){
        // 打印记录信息
        // console.log("----++-----Record...")
        // 将符合条件的数据添加到搜索结果数组中
        // dataCSV.push(str)
        dataSearchData.push(e)
      }
    }
  }
  // 打印最终的搜索结果数据
  console.log("------------",dataSearchData)

  // 调用函数将结果数据写入JSON文件
  transfer.jsonWrite(res, dataSearchData , 700)
}


module.exports = router
